package com.ruoyi.reportInfo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.dataStatistics.domain.IndustrialStationAnalysisVo;
import com.ruoyi.reportInfo.domain.IndustrialStationOperationInfo;
import com.ruoyi.reportInfo.mapper.IndustrialStationOperationInfoMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.reportInfo.domain.bo.IndustrialStationBo;
import com.ruoyi.reportInfo.domain.vo.IndustrialStationVo;
import com.ruoyi.reportInfo.domain.IndustrialStation;
import com.ruoyi.reportInfo.mapper.IndustrialStationMapper;
import com.ruoyi.reportInfo.service.IIndustrialStationService;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 场站基本信息Service业务层处理
 *
 * @author yangzhen
 * @date 2025-11-24
 */
@RequiredArgsConstructor
@Service
public class IndustrialStationServiceImpl implements IIndustrialStationService {

    private final IndustrialStationMapper baseMapper;

    private final IndustrialStationOperationInfoMapper industrialStationOperationInfoMapper;

    /**
     * 查询场站基本信息
     */
    @Override
    public IndustrialStationVo queryById(String id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询场站基本信息列表
     */
    @Override
    public TableDataInfo<IndustrialStationVo> queryPageList(IndustrialStationBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<IndustrialStation> lqw = buildQueryWrapper(bo);
        Page<IndustrialStationVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    @Override
    public TableDataInfo<IndustrialStationVo> industrialStationPageList(IndustrialStationBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<IndustrialStation> lqw = buildQueryWrapper(bo);
        Page<IndustrialStationVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);

        List<IndustrialStationVo> records = result.getRecords();
        if (records != null && !records.isEmpty()) {

            // 1. 获取本次分页内全部 stationId
            List<String> industrialStationIdList = records.stream()
                .map(IndustrialStationVo::getId)
                .collect(Collectors.toList());

            // 当前年份
            int currentYear = LocalDate.now().getYear();

            // 2. 一次查出所有站点的本年度运营数据（避免 N+1 查询）
            List<IndustrialStationOperationInfo> operationList =
                industrialStationOperationInfoMapper.selectList(
                    new LambdaQueryWrapper<IndustrialStationOperationInfo>()
                        .in(IndustrialStationOperationInfo::getStationId, industrialStationIdList)
                        .apply("YEAR(report_collect_date) = {0}", currentYear)
                        .orderByDesc(IndustrialStationOperationInfo::getReportDate)
                );

            // 按 stationId 分组
            Map<String, List<IndustrialStationOperationInfo>> operationGroupMap =
                operationList.stream().collect(Collectors.groupingBy(IndustrialStationOperationInfo::getStationId));

            // 3. 遍历 VO ，填充年度货运量 + 年度车次
            for (IndustrialStationVo vo : records) {

                List<IndustrialStationOperationInfo> operationInfos =
                    operationGroupMap.getOrDefault(vo.getId(), Collections.emptyList());

                if (operationInfos.isEmpty()) {

                    vo.setAnnualCargoVolume(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP));
                    vo.setAnnualCarNum(0L);
                    continue;
                }

                // 3.1 最新一条记录
                IndustrialStationOperationInfo latest = operationInfos.get(0);
                String reportCycle = latest.getReportCycle(); // “3” 年度，“2” 月度

                BigDecimal annualCargoVolume = BigDecimal.ZERO;

                if ("3".equals(reportCycle)) {
                    annualCargoVolume = Optional.ofNullable(latest.getFreightVolume()).orElse(BigDecimal.ZERO);
                } else if ("2".equals(reportCycle)) {
                    annualCargoVolume = operationInfos.stream()
                        .map(info -> Optional.ofNullable(info.getFreightVolume()).orElse(BigDecimal.ZERO))
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                }

                vo.setAnnualCargoVolume(annualCargoVolume.setScale(2, RoundingMode.HALF_UP));

                Long annualCarNum = 0L;

                if ("3".equals(reportCycle)) {
                    // 年度数据：直接取
                    annualCarNum = Optional.ofNullable(latest.getCarNum()).orElse(0L);

                } else if ("2".equals(reportCycle)) {
                    // 月度数据：累加全年
                    annualCarNum = operationInfos.stream()
                        .map(info -> Optional.ofNullable(info.getCarNum()).orElse(0L))
                        .reduce(0L, Long::sum);   // Long 累加
                }

                vo.setAnnualCarNum(annualCarNum);
            }
        }

        return TableDataInfo.build(result);
    }

    @Override
    public IndustrialStationAnalysisVo industrialStationAnalysis(IndustrialStationBo bo) {

        // 1. 获取统计年份
        Date statisticalYearDate = bo.getStatisticalYearDate();
        if (statisticalYearDate == null) {
            return null;
        }
        LocalDate localDate = statisticalYearDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        int year = localDate.getYear();

        // 2. 查询该年份所有月度运营信息
        List<IndustrialStationOperationInfo> operationList =
            industrialStationOperationInfoMapper.selectList(
                new LambdaQueryWrapper<IndustrialStationOperationInfo>()
                    .apply("YEAR(report_collect_date) = {0}", year)
                    .orderByAsc(IndustrialStationOperationInfo::getReportDate)
            );

        // 分组：按月份
        Map<Integer, List<IndustrialStationOperationInfo>> monthGroup = operationList.stream()
            .collect(Collectors.groupingBy(info -> {

                LocalDate date = info.getReportDate().toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDate();

                return date.getMonthValue(); // 1 ~ 12 月
            }));

        // 3. 初始化 12 个月的数据列表
        List<Double> freightVolumeList = new ArrayList<>(Collections.nCopies(12, 0.0));
        List<Long> carNumList = new ArrayList<>(Collections.nCopies(12, 0L));

        // 4. 填充数据（无数据月份默认 0）
        for (int month = 1; month <= 12; month++) {

            List<IndustrialStationOperationInfo> monthData = monthGroup.get(month);

            if (monthData == null || monthData.isEmpty()) {
                freightVolumeList.set(month - 1, 0.00);  // ⭐ 两位小数
                carNumList.set(month - 1, 0L);
                continue;
            }

            // 【货运量统计（Double）】
            double sumFreight = monthData.stream()
                .map(info -> info.getFreightVolume() == null
                    ? 0.0
                    : info.getFreightVolume().doubleValue())
                .reduce(0.0, Double::sum);

            //货运量保留两位小数
            sumFreight = BigDecimal.valueOf(sumFreight)
                .setScale(2, RoundingMode.HALF_UP)
                .doubleValue();

            // 【车次数统计（Long）】
            Long sumCarNum = monthData.stream()
                .map(info -> info.getCarNum() == null
                    ? 0L
                    : info.getCarNum())
                .reduce(0L, Long::sum);

            freightVolumeList.set(month - 1, sumFreight);
            carNumList.set(month - 1, sumCarNum);
        }

        // 5. 封装结果
        IndustrialStationAnalysisVo vo = new IndustrialStationAnalysisVo();
        vo.setFreightVolume(freightVolumeList);
        vo.setCarNum(carNumList);

        return vo;
    }



    /**
     * 查询场站基本信息列表
     */
    @Override
    public List<IndustrialStationVo> queryList(IndustrialStationBo bo) {
        LambdaQueryWrapper<IndustrialStation> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<IndustrialStation> buildQueryWrapper(IndustrialStationBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<IndustrialStation> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getStationName()), IndustrialStation::getStationName, bo.getStationName());
        lqw.eq(StringUtils.isNotBlank(bo.getStationType()), IndustrialStation::getStationType, bo.getStationType());
        lqw.eq(StringUtils.isNotBlank(bo.getMainGoodsType()), IndustrialStation::getMainGoodsType, bo.getMainGoodsType());
        lqw.eq(StringUtils.isNotBlank(bo.getUnifiedSocialCode()), IndustrialStation::getUnifiedSocialCode, bo.getUnifiedSocialCode());
        lqw.eq(StringUtils.isNotBlank(bo.getOperatorCompany()), IndustrialStation::getOperatorCompany, bo.getOperatorCompany());
        lqw.eq(bo.getArea() != null, IndustrialStation::getArea, bo.getArea());
        lqw.eq(StringUtils.isNotBlank(bo.getAddress()), IndustrialStation::getAddress, bo.getAddress());
        lqw.eq(StringUtils.isNotBlank(bo.getLongitude()), IndustrialStation::getLongitude, bo.getLongitude());
        lqw.eq(StringUtils.isNotBlank(bo.getLatitude()), IndustrialStation::getLatitude, bo.getLatitude());
        lqw.eq(StringUtils.isNotBlank(bo.getBelongParkId()), IndustrialStation::getBelongParkId, bo.getBelongParkId());
        lqw.like(StringUtils.isNotBlank(bo.getBelongParkName()), IndustrialStation::getBelongParkName, bo.getBelongParkName());
        lqw.eq(StringUtils.isNotBlank(bo.getManager()), IndustrialStation::getManager, bo.getManager());
        lqw.eq(StringUtils.isNotBlank(bo.getManagerContact()), IndustrialStation::getManagerContact, bo.getManagerContact());
        lqw.eq(StringUtils.isNotBlank(bo.getFileList1()), IndustrialStation::getFileList1, bo.getFileList1());
        lqw.eq(StringUtils.isNotBlank(bo.getFileList2()), IndustrialStation::getFileList2, bo.getFileList2());
        lqw.eq(StringUtils.isNotBlank(bo.getFileList3()), IndustrialStation::getFileList3, bo.getFileList3());
        lqw.eq(StringUtils.isNotBlank(bo.getFileList4()), IndustrialStation::getFileList4, bo.getFileList4());
        lqw.eq(StringUtils.isNotBlank(bo.getFileList5()), IndustrialStation::getFileList5, bo.getFileList5());
        lqw.eq(bo.getDataStatus() != null, IndustrialStation::getDataStatus, bo.getDataStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getDataSources()), IndustrialStation::getDataSources, bo.getDataSources());
        lqw.eq(bo.getCollectDate() != null, IndustrialStation::getCollectDate, bo.getCollectDate());
        lqw.eq(bo.getReportCollectDate() != null, IndustrialStation::getReportCollectDate, bo.getReportCollectDate());
        return lqw;
    }

    /**
     * 新增场站基本信息
     */
    @Override
    public Boolean insertByBo(IndustrialStationBo bo) {
        IndustrialStation add = BeanUtil.toBean(bo, IndustrialStation.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改场站基本信息
     */
    @Override
    public Boolean updateByBo(IndustrialStationBo bo) {
        IndustrialStation update = BeanUtil.toBean(bo, IndustrialStation.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(IndustrialStation entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除场站基本信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
